/*
 *
 * Copyright (C) 2008 Jose Javier García Zornoza.
 * 
 * Este es un programa libre; puedes distribuirlo y/o modificarlo bajo
 * los términos de la versión 2 (o cualquier versión posterior) de la Licencia 
 * Pública General de la Fundación de Software Libre.
 * Este programa se distribuye con la esperanza  de poder ser útil, pero sin
 * NINGUNA GARANTIA; tampoco la garantía implícita de COMERCIALIZACION o DEDICACIÓN
 * A UN PROPOSITO PARTICULAR. Ver la licencia GNU GPL para más detalles.
 * Deberías haber recibido una copia de la licencia GNU GPL con este programa;
 * en caso contrario puedes obtener una copia visitando el sitio web www.fsf.org
 * o escribiendo a la Fundación de Software Libre, Inc., 59 Temple 
 * Place - Suite 330, Boston, MA  02111-1307, USA. 
 *
 */
package org.gruposp2p.dnie.utils;
        
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.validation.Schema;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.bind.Unmarshaller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class XmlUtils {

    private static Logger logger = LoggerFactory.getLogger(XmlUtils.class);    

    public XmlUtils() {}

    public static Document getDocumentFromFile (File file, boolean validating) 
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
        factory.setValidating(validating);
        DocumentBuilder db = factory.newDocumentBuilder();
        db.setErrorHandler(new org.apache.xml.security.utils
            .IgnoreAllErrorHandler());
        Document doc = db.parse(file);
        return doc;
    }
    
    public static Document getDocumentFromFilePath (
            String filePath, boolean validating)
            throws ParserConfigurationException, SAXException, IOException {
        File file = new File(filePath);
        return getDocumentFromFile (file, validating);    
    }
    
    public static String getStringFromDocument (Document doc) {
        String respuesta = null;
        try {
//            OutputFormat format = new OutputFormat(doc, "ISO-8859-1", true);
            OutputFormat format = new OutputFormat(doc, "UTF-8", false);
            format.setStandalone(true);
            format.setIndenting(true);
            StringWriter stringOut = new StringWriter();
            XMLSerializer serial = new XMLSerializer(stringOut, format);
            serial.asDOMSerializer();
            serial.serialize(doc.getDocumentElement());
            respuesta = stringOut.toString();    
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
        return respuesta;
    }
        
    public static Document getDocumentFromString (
            String strDocument, boolean validating)
        throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
        factory.setValidating(validating);
        DocumentBuilder db = factory.newDocumentBuilder();
        db.setErrorHandler(new org.apache.xml.security.utils
            .IgnoreAllErrorHandler());
        return db.parse(new InputSource(new StringReader(strDocument)));
    }

    public static boolean validateXML (Document doc, Schema schema) throws Exception {
        Unmarshaller unmarshaller = null;
        boolean resultado = false;
        try {
            //validar XML contra el schema
            unmarshaller.setSchema(schema);
            unmarshaller.setEventHandler(
                new ValidationEventHandler() {
                    public boolean handleEvent(ValidationEvent ve) {
                        if (ve.getSeverity() != ValidationEvent.WARNING) {
                            ValidationEventLocator vel = ve.getLocator();
                            logger.info("Linea:Col[" + vel.getLineNumber() +
                                ":" + vel.getColumnNumber() +
                                "]:" + ve.getMessage());
                        }
                        return true;
                    }
                }
            );
            unmarshaller.unmarshal(doc.getDocumentElement());     
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
        return resultado;
    }
    
}
